package com.eshop.modules.security.service;

import org.slf4j.LoggerFactory;
import java.io.IOException;
import com.eshop.utils.FileUtil;
import java.util.LinkedHashMap;
import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.eshop.utils.PageUtil;
import java.util.Map;
import org.springframework.data.domain.Pageable;
import com.eshop.modules.user.vo.OnlineUser;
import java.util.Date;
import com.eshop.utils.EncryptUtils;
import com.eshop.utils.StringUtils;
import javax.servlet.http.HttpServletRequest;
import com.eshop.modules.security.security.vo.JwtUser;
import com.eshop.utils.RedisUtils;
import com.eshop.modules.security.config.SecurityProperties;
import org.slf4j.Logger;
import org.springframework.stereotype.Service;

@Service
public class OnlineUserService
{
    private static final Logger log;
    private final SecurityProperties properties;
    private RedisUtils redisUtils;
    
    public OnlineUserService(final SecurityProperties properties, final RedisUtils redisUtils) {
        this.properties = properties;
        this.redisUtils = redisUtils;
    }
    
    public void save(final JwtUser jwtUser, final String token, final HttpServletRequest request) {
        final String job = jwtUser.getDept() + "/" + jwtUser.getJob();
        final String ip = StringUtils.getIp(request);
        final String browser = StringUtils.getBrowser(request);
        final String address = StringUtils.getCityInfo(ip);
        OnlineUser onlineUser = null;
        try {
            onlineUser = new OnlineUser(jwtUser.getUsername(), jwtUser.getNickName(), job, browser, ip, address, EncryptUtils.desEncrypt(token), new Date());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        this.redisUtils.set(this.properties.getOnlineKey() + token, onlineUser, this.properties.getTokenValidityInSeconds() / 1000L);
    }
    
    public Map<String, Object> getAll(final String filter, final int type, final Pageable pageable) {
        final List<OnlineUser> onlineUsers = this.getAll(filter, type);
        return (Map<String, Object>)PageUtil.toPage(PageUtil.toPage(pageable.getPageNumber(), pageable.getPageSize(), (List)onlineUsers), onlineUsers.size());
    }
    
    public List<OnlineUser> getAll(final String filter, final int type) {
        List<String> keys = null;
        if (type == 1) {
            keys = (List<String>)this.redisUtils.scan("app-online-token:*");
        }
        else {
            keys = (List<String>)this.redisUtils.scan(this.properties.getOnlineKey() + "*");
        }
        Collections.reverse(keys);
        final List<OnlineUser> onlineUsers = new ArrayList<OnlineUser>();
        for (final String key : keys) {
            final OnlineUser onlineUser = (OnlineUser)this.redisUtils.get(key);
            if (StringUtils.isNotBlank((CharSequence)filter)) {
                if (!onlineUser.toString().contains(filter)) {
                    continue;
                }
                onlineUsers.add(onlineUser);
            }
            else {
                onlineUsers.add(onlineUser);
            }
        }
        onlineUsers.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
        return onlineUsers;
    }
    
    public void kickOut(String key) throws Exception {
        key = this.properties.getOnlineKey() + EncryptUtils.desDecrypt(key);
        this.redisUtils.del(new String[] { key });
    }
    
    public void kickOutT(final String key) throws Exception {
        final String keyt = "app-online-token:" + EncryptUtils.desDecrypt(key);
        this.redisUtils.del(new String[] { keyt });
    }
    
    public void logout(final String token) {
        final String key = this.properties.getOnlineKey() + token;
        this.redisUtils.del(new String[] { key });
    }
    
    public void download(final List<OnlineUser> all, final HttpServletResponse response) throws IOException {
        final List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (final OnlineUser user : all) {
            final Map<String, Object> map = new LinkedHashMap<String, Object>();
            map.put("用户名", user.getUserName());
            map.put("用户昵称", user.getNickName());
            map.put("登录IP", user.getIp());
            map.put("登录地点", user.getAddress());
            map.put("浏览器", user.getBrowser());
            map.put("登录日期", user.getLoginTime());
            list.add(map);
        }
        FileUtil.downloadExcel((List)list, response);
    }
    
    public OnlineUser getOne(final String key) {
        return (OnlineUser)this.redisUtils.get(key);
    }
    
    public void checkLoginOnUser(final String userName, final String igoreToken) {
        final List<OnlineUser> onlineUsers = this.getAll(userName, 0);
        if (onlineUsers == null || onlineUsers.isEmpty()) {
            return;
        }
        for (final OnlineUser onlineUser : onlineUsers) {
            if (onlineUser.getUserName().equals(userName)) {
                try {
                    final String token = EncryptUtils.desDecrypt(onlineUser.getKey());
                    if (StringUtils.isNotBlank((CharSequence)igoreToken) && !igoreToken.equals(token)) {
                        this.kickOut(onlineUser.getKey());
                    }
                    else {
                        if (!StringUtils.isBlank((CharSequence)igoreToken)) {
                            continue;
                        }
                        this.kickOut(onlineUser.getKey());
                    }
                }
                catch (Exception e) {
                    OnlineUserService.log.error("checkUser is error", (Throwable)e);
                }
            }
        }
    }
    
    static {
        log = LoggerFactory.getLogger((Class)OnlineUserService.class);
    }
}
